1. Field of the Invention
The embodiments of the invention generally relate to software application development, and more particularly to Java®-based security and authorization software application development systems and methods.
2. Description of the Related Art
Security and authorization play very important roles in the development, deployment, and functioning of software systems. Java®, available from Sun Microsystems, Inc., Santa Clara, Calif., USA, is the most popular platform for component-based software and systems. Moreover, Java® security plays a key role in e-commerce enterprise systems. Security features are typically built into an application in an ad-hoc manner or integrated with an enterprise J2EE® (Java® 2 Platform Enterprise Edition), available from Sun Microsystems, Inc., Santa Clara, Calif., USA, application using container managed authentication and authorization. There are several reasons for such a situation. First, security must be handled by nearly all of the components of the application; however its integration in the software development is not centralized. Second, there is a lack of a standard easy-to-use process for developing granular security. In J2EE® systems, containers provide method-level security and role-based access control which may not be sufficient for many situations. Overall, the low-level of security development makes security implementation rigid and tightly coupled with the application.
Java® Authentication and Authorization Service (JAAS) is a Java® package that enables services to authenticate and enforce access controls on users. In other words, JAAS is a set of Java® Application Program Interfaces (APIs) that can be used for two purposes: (1) for authentication of users, to reliably and securely determine who is currently executing Java® code, regardless of whether the code is running as an application, an applet, a bean, or a servlet; and (2) for authorization of users to determine if the authenticated user is allowed to access the resource (which can be the Java® code or some object/entity accessed by the Java® code), regardless of whether the code is running as an application, an applet, a bean, or a servlet. Typically, JAAS authentication is performed in a pluggable fashion. This permits Java® applications to remain independent from the underlying authentication technologies. Moreover, new or updated technologies can be plugged in without requiring modifications to the application itself.
Java® uses three types of defense mechanisms: byte-code verifier, class loader, and security manager. In Java® Version 1.0, applets operate in a “sandbox,” which restricts the applet's ability to either affect the machine they are executed on or to obtain any sensitive information from it. As such, nothing much can be accessed locally. In later versions of Java®, applets are allowed to escape the sandbox if the machine running it allows it to do so based on signing information. To support flexible, fine gained access control, Java® version 1.2 provides for policy based security architecture. The policy is defined by a set of permissions for code in various locations and by various signers. Permission allows access to certain actions on a certain resource. Usually, resource names and their associated actions are enumerated in a policy file. FIG. 1 illustrates a typical policy file in Java®.
In Java® version 2, two functions, earlier provided by the SecurityManager, namely establishment of security policy and enforcement of security policy, are separated. The java.security.Policy abstract class is used for establishing the security policy and the AccessController is used as the security enforcer. For backward compatibility, the SecurityManager class still exists but it refers to the AccessController for its decisions. In java.policy, permissions are associated with the code-source. As such, it does not have user or role based permissions. FIG. 2 illustrates a typical code for protecting a Java® method using AccessController. The example illustrated in FIG. 2 shows how a resource is protected by calling the AccessController before accessing the resource. The AccessController checks the requested permission with the application's current authorization policy. If any permission defined in the policy file implies the requested permission, the method “checkpermission” command simply returns; otherwise an AccessControlException is initiated.
As mentioned above, JAAS is a set of APIs that enable services to authenticate and enforce access controls upon users. JAAS reliably and securely determines who is currently executing the Java® code and whether it is allowed to do so. Moreover, JAAS implements a Java® technology version of the standard Pluggable Authentication Module (PAM) framework. This permits Java® applications to remain independent from the underlying authentication mechanism.
JAAS includes two primary components: authentication and authorization. JAAS adds subject based policies to the Java® version 2 security model. Permission is granted not only based on the CodeSource but also based on the user executing the code. For this the user is first authenticated. JAAS distribution contains various LoginModules implementations to retrieve the user id and password from the user. The LoginContext uses a login configuration file to determine which LoginModule to use for authentication. The Subject class is used to encapsulate the credentials of the authenticated user. A subject can have multiple identities called principals. In the JAAS policy file each grant statement is associated with a principal. For each principal associated with the subject, the AccessController obtains permissions from the PolicyFile and checks whether any permission implies the requested permission. Otherwise, the AccessController initiates an AccessControlException. FIG. 3 illustrates the typical policy for principal based authorization in JAAS.
In J2EE® architecture, a container serves as an authorization boundary between the components it hosts and their callers. The container establishes the identity of the user of the calling code. Access to the called component, an EJB (Enterprise JavaBeans™, available from Sun Microsystems, Inc., Santa Clara, Calif., USA), or a web component, is determined by comparing the caller's security attributes with those required to access the called component. In declarative authorization, a deployer establishes the container-enforced access control rules for a J2EE® application. The deployer maps an application permission model, typically supplied by the application assembler, to mechanisms specific to the runtime environment. The deployment descriptor defines security roles and their associated access rights for various components. The deployer assigns security roles to specific callers to establish the access rights of users in the runtime environment. For example, a deployer can map a security role to a list of principal identities in the operational environment. Then, callers, authenticated with one of these identities, are assigned the privilege represented by the role. A J2EE® container makes access control decisions before the dispatching method calls to a component. Thus, declarative access control can be assigned with the method's granularity.
The J2EE® container does not factor in the logic or state of the component in these access decisions. To do that, programmatic authorization is required to be performed by the code developer. A component can use two methods to perform fine-grained access control: EJBContext.isCallerInRole (for EJB components) and HttpServletRequest.isUserInRole (for web components). A component uses these methods to determine whether a caller has been granted a privilege selected by the component based on the parameters of the call, the internal state of the component, or other factors such has runtime parameters. However, there is a trade-off between the declarative and programmatic authorization. The declarative authorization is an external access control policy configured by the deployer whereas the programmatic authorization is through an internal policy embedded in the application by the component developer. The internal policy is more fine-grained whereas the external policy is more flexible. Moreover, the external policy is transparent whereas the internal policy is buried in the application. For example, to provide the authorization policy, “Employees can only access their own salary information,” programmatic authorization is required, which cannot be changed in the future, if required.
Moreover, JAAS is built on top of the pre-existing security model of Java®, which is CodeSource based and the plaintext format policy file implementation. JAAS implements authorization based on the class accessed by a certain component. However, this may not be sufficient for an enterprise application, whereby one may wish to use the custom security repositories, like LDAP (Lightweight Directory Access Protocol) with JAAS. Further, in business-to-business electronic commerce a pricing contract may have different access control policies than another contract. The specification for a self-service auction application might have the requirement that “any registered user can create an auction but only the user who created the auction is allowed to modify it.” Thus, many Java® applications are required to extend JAAS to satisfy its authorization requirements. Because of pluggable features of JAAS, one can write his/her own implementation of various authentication and authorization sub-modules to change the default behavior of JAAS. For the authorization requirements illustrated in the above examples, one may need to change the default implementations of one or more of the following:                java.security.Permission: The AccessController.checkPermission (Permission perm) is called to determine whether the caller has the authority to perform the action on the called CodeSource. The permission object perm represents the required access to a resource. The permission object can specify things such as name of the permission (which may indicate the resource on which access is required), action for which the resource is accessed, etc. The permission class implements an implied method to be called by the AccessController to determine whether a granted permission implies the requested permission. For implementing class instance level authorization, one needs to have a new implementation of permissions having an object instance as one of its field. That object can be used in the implied method to decide authorizations.        java.security.PermissionCollection: This abstract class is used for representing a collection of permission objects. This class can be implemented to have a desired manner of storing the granted permissions and comparing them with the requested permission to determine if any of the granted permissions implies a requested permission.        java.security.Policy: This is an abstract class for storing security policies in a Java® application environment. The AccessController contacts the policy implementation to obtain the permissions for an authenticated subject on a CodeSource. The policy object consults its policy specification and returns an appropriate PermissionCollection object enumerating the permissions that are allowed. By default, sun.security.provider.PolicyFile implementation is used for policy implementation. By having different implementation one can change the way policies are written (for example, LDAP or software applications) or additional parameters on which the authorization depends.        javax.security.auth.spi.LoginModule: The LoginModule describes the interface implemented by the authentication provider. It retrieves the username and password(s) from the callbacks, which, by default, performs some user interaction. The LoginModule can be extended to delegate the authentication to some external adaptor.        java.security.Principal: The Principal interface represents the abstract notion to be used to represent an entity such as an individual, an organization, a group, or a login id. Group, KerberosPrincipal, etc. are well known implementations of Principal. By extending the Principal one can add custom properties to be used for authorization.        
However, one of the limitations of JAAS is that it does not support class instance level authorization; i.e., the authorization in JAAS is performed on the basis of the class name and not on the basis of a specific instance of the class. For example, the specification for a web-based, self-service auction application may have the following requirement: “Any registered (authenticated) user can create an auction but only the user who created the auction may modify it.” This means that any user can execute the code written to create an auction class instance, but only the user who owns that instance may execute code designed to modify it. Usually, the user who created the auction instance will be the owner. What this implies is that people of the same role might have different access rights based on their attributes or the actions that they have performed in the past. Unfortunately, this type of authorization cannot be supported using JAAS.
JAAS authorization extends the existing Java® security architecture that uses a security policy to specify what access rights are granted to the executing code. This security architecture, as provided in the Java® version 2 platform, is code-centric. That is, the permissions are granted based on code characteristics; i.e., where the code is coming from and whether it is digitally signed and if so, by whom. With the integration of JAAS into the Java® 2 SDK (Software Development Kit), the java.security.Policy API handles principal-based queries, and the default policy implementation supports principal-based grant entries. Thus, access control can now be based on which code is running, as well as who is running the code.
JAAS does provide a mechanism to support instance level JAAS. This is accomplished by extending some of the classes that are used by JAAS. However, the main drawback of this approach is that it is not extensible and it requires the creation of a new authorization class and a significant amount of rework if different kinds of authorizations in different domains are to be provided. Another option for supporting instance level authorization is to use a custom authorization code which is coded as part of the application. Generally, this is the most widely used method to support the authorization technique and the major drawback of this is that it is not based on standards making it more difficult to apply in different applications. Furthermore, since the code is part of the application, it is difficult to maintain and because it is non-generic it generally cannot be reused in different domains.
Therefore, due to the drawbacks and limitations of the conventional approaches, there remains a need for a more universally applicable JAAS-based authorization solution, which can be applied to different domains without requiring any new code. Writing new code for a new authorization requirement makes it difficult to change authorization settings at deployment time. Thus, what is needed is the flexibility of a declarative authorization with the high granularity of programmatic authorization.